package org.oos.dao;

import java.io.File;
import java.io.InputStream;
import java.util.List;
import java.util.logging.Logger;

import org.oos.atom.AtomEntity;
import org.oos.atom.AtomFeed;
import org.oos.auth.AuthenticationHandler;
import org.oos.dao.exceptions.CreationException;
import org.oos.dao.exceptions.DeleteException;
import org.oos.dao.exceptions.ReadException;
import org.oos.dao.exceptions.UpdateException;
import org.oos.dao.options.OptionsMap;
import org.oos.lists.DynamicList;

/**
 * Structure of simple DAO with CRUD, Logging and size. Extensions of this
 * interface are expected to extend {@link AbstractDao}. Not using this base
 * class may break something in the future.
 * 
 * @author pablo.gonzalez@11870.com
 * 
 */
public interface Dao<Entry extends AtomEntity, Feed extends AtomFeed<Entry>> {

	/**
	 * Set the {@link Logger} relevant to the DAO
	 * 
	 * @param log
	 * @return
	 */
	public Dao<Entry, Feed> setLog(Logger log);

	/**
	 * @return a Logger relevant to the DAO.
	 */
	public Logger getLog();

	/**
	 * @return a list of {@link OptionsMap} to add/remove options. It gets used
	 *         every time a new request is provided.
	 */
	public List<OptionsMap> getOptions();

	public Dao<Entry, Feed> setAuthenticationHandler(
			AuthenticationHandler authHandler);

	/**
	 * 
	 * Creates the provided item.
	 * 
	 * @param entry
	 * @return
	 * @throws CreationException
	 */
	public Entry create(Entry entry) throws CreationException;

	public Entry create() throws CreationException;

	public Entry createMedia(File file, String contentType) throws CreationException;

	/**
	 * 
	 * Read all the Items as a {@link List}
	 * 
	 * @return
	 * @throws ReadException
	 */
	public <L extends DynamicList<Entry>> L read() throws ReadException;

	/**
	 * 
	 * Reads the item at the provided position (index)
	 * 
	 * @param index
	 *            position to read
	 * @return
	 * @throws ReadException
	 */
	public Entry read(Integer index) throws ReadException;
	
	public Entry readEntry(String param) throws ReadException;
	
	public InputStream readMedia(String param) throws ReadException;

	/**
	 * 
	 * Applies the changes of the information in the provided Item.
	 * 
	 * @param entry
	 * @return
	 * @throws UpdateException
	 */
	public boolean update(Entry entry) throws UpdateException;
	
	public boolean updateMedia(Entry entry, File file, String contentType) throws UpdateException;

	/**
	 * 
	 * Removes the provided Item.
	 * 
	 * @param entry
	 * @return
	 * @throws DeleteException
	 */
	public boolean delete(Entry entry) throws DeleteException;
	
	public boolean deleteMedia(Entry entry) throws DeleteException;

	/**
	 * @return the available number for items.
	 * @throws ReadException
	 */
	public int size() throws ReadException;

	public Feed readFeed(Integer index) throws ReadException;
	
//	public Feed readFeed(Integer start, Integer end)  throws ReadException;

}
